#include <iostream>
#include <fstream>
#include <cstring>
#include <thread>
#include <vector>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include "ikcp.h"

#define KCP_MTU 1400
#define REMOTE_IP "127.0.0.1"
#define REMOTE_PORT 5001
#define CONTROL_MAGIC 0xAABBCCDD
#define DATA_MAGIC 0x11223344

static inline uint32_t ikcp_getms() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
//发送udp流
int udp_output(const char *buf, int len, ikcpcb *kcp, void *user) {
    int sockfd = *(int*)user;
    struct sockaddr_in dest_addr;
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(REMOTE_PORT);
    dest_addr.sin_addr.s_addr = inet_addr(REMOTE_IP);
    sendto(sockfd, buf, len, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
    return len;
}

//发送文件的函数
void sendFile(const std::string& filename, uint32_t conv) {
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in remote_addr;
    remote_addr.sin_family = AF_INET;
    remote_addr.sin_port = htons(REMOTE_PORT);
    remote_addr.sin_addr.s_addr = inet_addr(REMOTE_IP);

    // 发送控制包
    char ctrl_buf[16 + filename.size()];
    uint32_t magic = CONTROL_MAGIC;
    memcpy(ctrl_buf, &magic, 4);
    memcpy(ctrl_buf + 4, &conv, 4);
    uint16_t name_len = filename.size();
    memcpy(ctrl_buf + 8, &name_len, 2);
    memcpy(ctrl_buf + 10, filename.c_str(), name_len);
    printf("通过udp协议发送文件名-》sendto");
    sendto(sockfd, ctrl_buf, 10 + name_len, 0, (struct sockaddr*)&remote_addr, sizeof(remote_addr));

    // 创建KCP实例
    ikcpcb* kcp = ikcp_create(conv, (void*)&sockfd);
    kcp->output = udp_output;
    ikcp_wndsize(kcp, 128, 128);
    ikcp_nodelay(kcp, 1, 10, 2, 1);

    // 读取文件数据并发送
    std::ifstream file(filename, std::ios::binary);
    if (!file) {
        std::cerr << "Failed to open file: " << filename << std::endl;
        ikcp_release(kcp);
        close(sockfd);
        return;
    }

    file.seekg(0, std::ios::end);
    size_t file_size = file.tellg();
    file.seekg(0, std::ios::beg);

    printf("文件内容全部读取到数组中\n");
    char *file_data = new char[file_size];
    file.read(file_data, file_size);
    file.close();

    size_t sent = 0;
    printf("通过循环发送文件数组内容\n");
    while (sent < file_size) {
        int len = std::min((size_t)KCP_MTU, file_size - sent);
        ikcp_send(kcp, file_data + sent, len);
        sent += len;
        ikcp_update(kcp, ikcp_getms());
    }
//文件发送完毕
printf("文件发送完毕\n");
    delete[] file_data;
    ikcp_release(kcp);
    printf("关闭udp\n");
    close(sockfd);
}

int main() {
    // 读取多个文件的列表
    std::vector<std::string> files = {"file1.txt"};
    std::vector<std::thread> threads;
    uint32_t conv = 0x11223344;
    for (const auto& file : files) {
        threads.emplace_back(sendFile, file, conv++);
    }
    for (auto& t : threads) {
        t.join();
    }
    return 0;
}